package org.foj.presenter {
import mx.collections.ArrayCollection;

import mx.controls.Alert;
import mx.rpc.AsyncResponder;

import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

import org.foj.dto.Issue;
import org.foj.dto.User;
import org.foj.event.EventDispatcherFactory;
import org.foj.event.UIEvent;
import org.foj.event.UserEvent;
import org.foj.model.IssueModel;
import org.foj.view.DetailView;

public class DetailPresenter {
    private var _currentUser:User;
    private var _issue:Issue;
    private var _view:DetailView;
    private var _issueModel:IssueModel;
    public function DetailPresenter(view:DetailView) {

        this._issueModel = new IssueModel();
        this._view = view;
        this._issue = new Issue();
        view.issueType.dataProvider = new ArrayCollection(
                ["Bug", "Feature Request", "Enhancement"]
                );
        view.issueSeverity.dataProvider = new ArrayCollection(
                ["Minor", "Major", "Severe"]
                );
        view.issueStatus.dataProvider = new ArrayCollection(
                ["Open", "In Progress", "On Hold", "Finished"]
                );
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.SELECTED_ISSUE_CHANGED,
                changedIssue);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.SAVE_ISSUE_BUTTON_CLICKED,
                saveIssue);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UIEvent.CANCELLED_ISSUE_EDIT,
                cancelChanges);
        EventDispatcherFactory.getEventDispatcher()
                .addEventListener(UserEvent.CURRENT_USER_UPDATED, currentUserChanged)
    }

    private function currentUserChanged(event:UserEvent):void {
        _currentUser = event.data;
        if (selectedIssue.id == 0) {
            _view.issueReportedBy.text = _currentUser == null ? "" : _currentUser.fullName;
        }
    }
    private function get selectedIssue():Issue {
        return this._issue;
    }
    private function set selectedIssue(issue:Issue):void {
        this._issue = issue;
        _view.issueId.text = issue.id == 0 ? "" : issue.id.toString();
        _view.projectName.text = issue.project;
        _view.issueDescription.text = issue.description;
        _view.issueType.selectedItem = issue.type;
        _view.issueSeverity.selectedItem = issue.severity;
        _view.issueStatus.selectedItem = issue.status;
        _view.issueDetails.text = issue.details;
        _view.issueReportedBy.text = issue.reportedBy;
        _view.issueReportedOn.selectedDate = issue.reportedOn;
        _view.issueAssignedTo.text = issue.assignedTo;
        _view.issueEstimatedHours.text = isNaN(issue.estimatedHours) ?
                                         "" : issue.estimatedHours.toString();
        _view.saveChangesButton.label = issue.id == 0 ?
                                        "Add Issue" : "Save Issue";
    }
    private function saveIssue(event:UIEvent = null):void {
        _issue.project = _view.projectName.text;
        _issue.description = _view.issueDescription.text;
        _issue.type = String(_view.issueType.selectedItem);
        _issue.severity = String(_view.issueSeverity.selectedItem);
        _issue.status = String(_view.issueStatus.selectedItem);
        _issue.details = _view.issueDetails.text;
        _issue.reportedOn = _view.issueReportedOn.selectedDate;
        _issue.reportedBy = _view.issueReportedBy.text;
        _issue.assignedTo = _view.issueAssignedTo.text;
        _issue.estimatedHours = !isNaN(Number(_view.issueEstimatedHours.text)) ?
                                Number(_view.issueEstimatedHours.text) : null;

        _issueModel.saveIssue(_issue,
            new AsyncResponder(saveIssueResult, handleError));
    }
    private function cancelChanges(event:UIEvent = null):void {
        selectedIssue = new Issue();
        selectedIssue.reportedBy = _currentUser.fullName;
        var event:UIEvent = new UIEvent(UIEvent.SELECTED_ISSUE_CHANGED);
        event.data = selectedIssue;
        EventDispatcherFactory.getEventDispatcher().dispatchEvent(event);
    }
    private function changedIssue(event:UIEvent):void {
        selectedIssue = event.data;
    }
    private function saveIssueResult(resultEvent:ResultEvent,
                                     token:AsyncToken = null):void {
        selectedIssue = new Issue(resultEvent.result);
        var event:UIEvent = new UIEvent(UIEvent.SELECTED_ISSUE_SAVED);
        event.data = _issue;
        EventDispatcherFactory.getEventDispatcher().dispatchEvent(event);
    }
    private function handleError(event:FaultEvent,
                                 token:AsyncToken = null):void {
        Alert.show(event.message.toString());
    }
}
}
